/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.libermundi.theorcs.security.dao.hibernate;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.Restrictions;
import org.libermundi.theorcs.core.dao.exception.OrcsDataAccessException;
import org.libermundi.theorcs.core.dao.hibernate.HibernateGenericDao;
import org.libermundi.theorcs.core.model.Uid;
import org.libermundi.theorcs.security.dao.UserDao;
import org.libermundi.theorcs.security.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;

/**
 * User Persistance Class
 *
 */
@Repository
public final class UserDaoImpl extends HibernateGenericDao<User,Long> implements UserDao {
	
	private static final Logger logger = LoggerFactory.getLogger(UserDaoImpl.class);
	
	public UserDaoImpl(){
		super();
		_mappedClazz = User.class;
	}		

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.security.dao.UserDao#getUserByUsername(java.lang.String, boolean)
	 */
	@Override
	public User getUserByUsername(String username, boolean force) throws DataAccessException{
		User result = null;
		try	{
			result = (User) createUserCriteria(force)
								.add(Restrictions.eq(User.PROP_USERNAME,username))
								.uniqueResult();
			if(logger.isDebugEnabled()) {
				logger.debug("getUserByUsername(" + username +") : " + result);
			}
		} catch (HibernateException e) {
			logger.error("Exception in getUserByUsername(" + username +")", e);
			throw new OrcsDataAccessException("Exception in getUserByUsername : " + username, e);
		}
		return result;
	}
	
	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.security.dao.UserDao#getUserByNickname(java.lang.String, boolean)
	 */
	@Override
	public User getUserByNickname(String nickname, boolean force) {
		User result = null;
		try	{
			result = (User) createUserCriteria(force)
								.add(Restrictions.eq(User.PROP_NICKNAME,nickname))
								.uniqueResult();
			if(logger.isDebugEnabled()) {
				logger.debug("getUserByNickname(" + nickname +") : " + result);
			}
		} catch (HibernateException e) {
			logger.error("Exception in getUserByNickname(" + nickname +")", e);
			throw new OrcsDataAccessException("Exception in getUserByNickname : " + nickname, e);
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.security.dao.UserDao#getUserByUID(java.lang.String, boolean)
	 */
	
	@Override
	public User getUserByUID(String uid, boolean force) {
		User result = null;
		try	{
			result = (User) createUserCriteria(force)
								.add(Restrictions.eq(Uid.PROP_UID,uid))
								.uniqueResult();
			if(logger.isDebugEnabled()) {
				logger.debug("getUserByUID(" + uid +") : " + result);
			}
		} catch (HibernateException e) {
			logger.error("Exception in getUserByUID(" + uid +")", e);
			throw new OrcsDataAccessException("Exception in getUserByUID : " + uid, e);
		}
		return result;
	}
	
	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.security.dao.UserDao#getUserByEmail(java.lang.String, boolean)
	 */
	@Override
	public User getUserByEmail(String email, boolean force) {
		String emailToFind = email.toLowerCase();
		User result = null;
		try	{
			result = (User) createUserCriteria(force)
								.add(Restrictions.eq(User.PROP_EMAIL,emailToFind))
								.uniqueResult();
			if(logger.isDebugEnabled()) {
				logger.debug("getUserByEmail(" + emailToFind +") : " + result);
			}
		} catch (HibernateException e) {
			logger.error("Exception in getUserByEmail(" + emailToFind +")", e);
			throw new OrcsDataAccessException("Exception in getUserByEmail : " + emailToFind, e);
		}
		return result;
	}

	private Criteria createUserCriteria(boolean force) {
		Criteria criteria = null;
		if(!force){
			criteria = createSafeCriteria();
			criteria.add(Restrictions.eq(User.PROP_ENABLED, Boolean.TRUE));
		} else {
			criteria = createSimpleCriteria();
		}
		return criteria;
	}
	
}
